package com.yss.reportworld.service.impl;

import java.sql.Connection;
import java.util.*;
import java.util.stream.Collectors;

import com.alibaba.excel.ExcelWriter;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.yss.common.core.constant.RequestDataHelper;
import com.yss.common.core.domain.*;
import com.yss.common.core.enums.YssDataBaseEnum;
import com.yss.common.core.enums.YssStatusEnum;
import com.yss.common.core.exception.BusinessException;
import com.yss.common.core.utils.JdbcUtil;
import com.yss.common.core.utils.StringUtils;
import com.yss.common.core.utils.easyexecl.EasyExeclUtil;
import com.yss.common.core.utils.file.FileUtils;
import com.yss.common.core.utils.uuid.IdUtils;
import com.yss.common.security.utils.DictUtils;
import com.yss.common.security.utils.SecurityUtils;
import com.yss.reportworld.domain.*;
import com.yss.reportworld.enums.ReportWorldEnum;
import com.yss.reportworld.mapper.*;
import com.yss.reportworld.service.*;
import com.yss.reportworld.util.TableInfoUtil;
import lombok.extern.slf4j.Slf4j;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import oracle.jdbc.driver.OracleConnection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jdbc.datasource.ConnectionHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;

/**
 * 报标世界信息Service业务层处理
 *
 * @author yss
 * @date 2023-03-19
 */
@Slf4j
@Service
public class TableServiceImpl extends ServiceImpl<TableMapper, Table> implements ITableService {
    @Autowired
    private TableMapper tableMapper;
    @Autowired
    private ITableDetailService tableDetailService;
    @Autowired
    private ITableIndexedService tableIndexedService;
    @Qualifier("dataSource")
    @Autowired
    private DataSource dataSource;
    @Autowired
    private IDatabaseCheckService databaseCheckService;
    @Autowired
    private DataReportMapper dataReportMapper;
    @Autowired
    private DataModularMapper dataModularMapper;
    @Autowired
    private DataCustomerMapper dataCustomerMapper;
    @Autowired
    private TableDetailMapper tableDetailMapper;
    @Autowired
    private TableIndexedMapper tableIndexedMapper;
    @Autowired
    private DataDemandBugMapper dataDemandBugMapper;
    @Autowired
    private IDataMapService dataMapService;

    /**
     * 查询表信息列表
     *
     * @param table 表信息
     * @return 表信息
     */
    @Override
    public List<Table> selectTableList(Table table, boolean dataMark) {
        try {
            TableInfoUtil.handleTableVersion(table.getHisVersion()); // 替换表名
            QueryWrapper<Table> wrapper = new QueryWrapper();
            if (StringUtils.isNotEmpty(table.getName())) {
                wrapper.like("a.NAME", table.getName());
            }
            if (StringUtils.isNotEmpty(table.getChineseName())) {
                wrapper.like("a.CHINESE_NAME", table.getChineseName());
            }
            if (null != table.getStatus()) {
                wrapper.eq("a.STATUS", table.getStatus());
            }
            if (null != table.getLayered()) {
                wrapper.eq("a.LAYERED", table.getLayered());
            }
            if (StringUtils.isNotEmpty(table.getVersion())) {
                wrapper.eq("a.VERSION", table.getVersion());
            }
            if (null != table.getFtype()) {
                wrapper.eq("a.FTYPE", table.getFtype());
            }
            if (null != table.getFsource()) {
                wrapper.eq("a.FSOURCE", table.getFsource());
            }
            if (StringUtils.isNotEmpty(table.getStrReport())) {
                wrapper.in("b.REPORT_ID", table.getStrReport());
            }
            if (StringUtils.isNotEmpty(table.getStrModular())) {
                wrapper.in("c.MODULAR_ID", table.getStrModular());
            }
            if (StringUtils.isNotEmpty(table.getStrCustomer())) {
                wrapper.in("d.CUSTOMER_ID", table.getStrCustomer());
            }
            // 导出的时候选择了数据，按照选择的数据
            if (StringUtils.isNotEmpty(table.getIds())) {
                List<String> list = JSONArray.parseArray(table.getIds(), String.class);
                if (StringUtils.isNotEmpty(list)) {
                    wrapper.in("a.ID", list);
                }
            }
            List<Table> list = tableMapper.queryTable(wrapper);
            if (StringUtils.isEmpty(list)) {
                return list;
            }
            if (dataMark) {
                for (Table tableInfo : list) {
                    this.setTableInfo(tableInfo);
                }
            }
            // 获取有依赖信息的表
            for (Table tableInfo : list) {
                QueryWrapper<DataMap> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("TABLE_NAME", tableInfo.getName());
                List<DataMap> dataMapList = dataMapService.list(queryWrapper);
                if (StringUtils.isEmpty(dataMapList)) {
                    continue;
                }
                tableInfo.setIsDataMap(1); // 前台显示表依赖信息
            }
            return list;
        } finally {
            RequestDataHelper.removeThreadLocal();
        }
    }

    private void setTableInfo(Table tableInfo) {
        // 所属模块
        DataModular modular = new DataModular();
        modular.setDataId(tableInfo.getId());
        modular.setDataCode(ReportWorldEnum.REPORT_TABLE_CODE.getCode());
        List<DataModular> listModular = dataModularMapper.selectPrimaryByDataId(modular);
        if (StringUtils.isNotEmpty(listModular)) {
            StringBuffer modularName = new StringBuffer();
            for (DataModular dataModular : listModular) {
                modularName.append(dataModular.getModularName()).append("/");
            }
            tableInfo.setStrModularName(modularName.deleteCharAt(modularName.length() - 1).toString());
            tableInfo.setStrModular(listModular.stream().map(DataModular::getModularId).collect(Collectors.toList()));
        }
        // 所属客户
        DataCustomer customer = new DataCustomer();
        customer.setDataId(tableInfo.getId());
        customer.setDataCode(ReportWorldEnum.REPORT_TABLE_CODE.getCode());
        List<DataCustomer> listCustomer = dataCustomerMapper.selectPrimaryByDataId(customer);
        if (StringUtils.isNotEmpty(listCustomer)) {
            StringBuffer customerName = new StringBuffer();
            for (DataCustomer dataCustomer : listCustomer) {
                customerName.append(dataCustomer.getCustomerName()).append("/");
            }
            tableInfo.setStrCustomerName(customerName.deleteCharAt(customerName.length() - 1).toString());
            tableInfo.setStrCustomer(listCustomer.stream().map(DataCustomer::getCustomerId).collect(Collectors.toList()));
        }
        // 所属报表
        DataReport report = new DataReport();
        report.setDataId(tableInfo.getId());
        report.setDataCode(ReportWorldEnum.REPORT_TABLE_CODE.getCode());
        List<DataReport> listReport = dataReportMapper.selectPrimaryByDataId(report);
        if (StringUtils.isNotEmpty(listReport)) {
            StringBuffer reportName = new StringBuffer();
            for (DataReport dataReport : listReport) {
                reportName.append(dataReport.getReportName()).append("/");
            }
            tableInfo.setStrReportName(reportName.deleteCharAt(reportName.length() - 1).toString());
            tableInfo.setStrReport(listReport.stream().map(DataReport::getReportId).collect(Collectors.toList()));
        }
    }

    /**
     * 获取 表详细信息  ，包含字段所属客户，模块。客户
     *
     * @param table
     * @return
     */
    public Table selectTableById(Table table) {
        try {
            TableInfoUtil.handleTableVersion(table.getHisVersion()); // 替换表名
            QueryWrapper<Table> wrapper = new QueryWrapper<>();
            wrapper.eq("a.ID", table.getId());
            List<Table> list = tableMapper.queryTable(wrapper);
            if (StringUtils.isEmpty(list) || StringUtils.isNull(list.get(0))) {
                return null;
            }
            Table tableInfo = list.get(0);
            this.setTableInfo(tableInfo);
            return tableInfo;
        } finally {
            RequestDataHelper.removeThreadLocal();
        }
    }

    /**
     * 添加表信息
     *
     * @param table
     * @return
     */
    @Override
    @Transactional
    public void addTable(Table table) {
        try {
            TableInfoUtil.handleTableVersion(table.getHisVersion()); // 替换表名
            if (!this.checkTableNameUnique(table)) {
                throw new BusinessException("表【" + table.getName() + "】已存在");
            }
            table.setId(IdUtils.fastSimpleUUID());
            table.setCreateBy(SecurityUtils.getUsername());
            table.setCreateTime(new Date());
            table.setName(table.getName().toUpperCase());
            this.addTableInfo(table);
            // 修改之前的表状态为已删除
            this.updateOriginalTableName(table);
            this.save(table);
            ConnectionHolder holder = (ConnectionHolder) TransactionSynchronizationManager.getResource(this.dataSource);
            Connection connection = holder.getConnection();
            if (null == connection) {
                throw new BusinessException("获取数据库连接出错，请稍后重试！");
            }
          /*  String msgInfo = databaseCheckService.checkDataBaseAllByCode(ReportWorldEnum.REPORT_TABLE_CODE.getDesc(), connection, "");
            if (StringUtils.isNotEmpty(msgInfo)) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                throw new BusinessException(msgInfo);
            }*/
        } finally {
            RequestDataHelper.removeThreadLocal();
        }
    }

    /**
     * 修改表信息
     *
     * @param table
     * @return
     */
    @Override
    @Transactional
    public void editTable(Table table) {
        try {
            TableInfoUtil.handleTableVersion(table.getHisVersion()); // 替换表名
            if (!this.checkTableNameUnique(table)) {
                throw new BusinessException("表【" + table.getName() + "】已存在");
            }
            table.setUpdateTime(new Date());
            table.setName(table.getName().toUpperCase());
            table.setUpdateBy(SecurityUtils.getUsername());
            //删除表和客户信息关联关系
            QueryWrapper<DataCustomer> wrapperCustomer = new QueryWrapper<>();
            wrapperCustomer.in("DATA_ID", table.getId());
            wrapperCustomer.eq("DATA_CODE", ReportWorldEnum.REPORT_TABLE_CODE.getCode());
            dataCustomerMapper.delete(wrapperCustomer);
            //删除表和模块信息关联关系
            QueryWrapper<DataModular> wrapperModular = new QueryWrapper<>();
            wrapperModular.in("DATA_ID", table.getId());
            wrapperModular.eq("DATA_CODE", ReportWorldEnum.REPORT_TABLE_CODE.getCode());
            dataModularMapper.delete(wrapperModular);
            //删除表和报表信息关联关系
            QueryWrapper<DataReport> wrapperReport = new QueryWrapper<>();
            wrapperReport.in("DATA_ID", table.getId());
            wrapperReport.eq("DATA_CODE", ReportWorldEnum.REPORT_TABLE_CODE.getCode());
            dataReportMapper.delete(wrapperReport);
            this.addTableInfo(table);
            // 修改之前的表状态为已删除
            this.updateOriginalTableName(table);
            this.updateById(table);
            ConnectionHolder holder = (ConnectionHolder) TransactionSynchronizationManager.getResource(this.dataSource);
            Connection connection = holder.getConnection();
            if (null == connection) {
                throw new BusinessException("获取数据库连接出错，请稍后重试！");
            }
            String msgInfo = databaseCheckService.checkDataBaseAllByCode(ReportWorldEnum.REPORT_TABLE_CODE.getDesc(), connection, "");
            if (StringUtils.isNotEmpty(msgInfo)) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                throw new BusinessException(msgInfo);
            }
        } finally {
            RequestDataHelper.removeThreadLocal();
        }
    }

    /**
     * 校验表名是否唯一
     *
     * @param table
     * @return 结果
     */
    private boolean checkTableNameUnique(Table table) {
        try {
            TableInfoUtil.handleTableVersion(table.getHisVersion()); // 替换表名
            String tableId = StringUtils.isNull(table.getId()) ? "-1" : table.getId();
            QueryWrapper<Table> wrapper = new QueryWrapper<>();
            wrapper.eq("NAME", table.getName());
            Table info = this.getOne(wrapper);
            if (StringUtils.isNotNull(info) && !info.getId().equals(tableId)) {
                return false;
            }
            return true;
        } finally {
            RequestDataHelper.removeThreadLocal();
        }
    }

    /**
     * 保存表的关联关系信息
     */
    private void addTableInfo(Table table) {
        if (StringUtils.isNotEmpty(table.getStrCustomer())) {
            for (String str : table.getStrCustomer()) {
                DataCustomer dataCustomer = new DataCustomer();
                dataCustomer.setId(IdUtils.fastSimpleUUID());
                dataCustomer.setCustomerId(str);
                dataCustomer.setDataId(table.getId());
                dataCustomer.setDataCode(ReportWorldEnum.REPORT_TABLE_CODE.getCode());
                dataCustomerMapper.insert(dataCustomer);
            }
        }
        if (StringUtils.isNotEmpty(table.getStrModular())) {
            for (String str : table.getStrModular()) {
                DataModular dataModular = new DataModular();
                dataModular.setId(IdUtils.fastSimpleUUID());
                dataModular.setModularId(str);
                dataModular.setDataId(table.getId());
                dataModular.setDataCode(ReportWorldEnum.REPORT_TABLE_CODE.getCode());
                dataModularMapper.insert(dataModular);
            }
        }
        if (StringUtils.isNotEmpty(table.getStrReport())) {
            for (String str : table.getStrReport()) {
                DataReport dataReport = new DataReport();
                dataReport.setId(IdUtils.fastSimpleUUID());
                dataReport.setReportId(str);
                dataReport.setDataId(table.getId());
                dataReport.setDataCode(ReportWorldEnum.REPORT_TABLE_CODE.getCode());
                dataReportMapper.insert(dataReport);
            }
        }
    }

    /**
     * 增加修改前表的时候，以前的表状态标识为已删除状态
     *
     * @param table
     */
    private void updateOriginalTableName(Table table) {
        if (StringUtils.isNull(table) || StringUtils.isBlank(table.getId()) || StringUtils.isBlank(table.getOriginalTableName())) {
            return;
        }
        // 查询以前字段的信息修改状态
        QueryWrapper<Table> wrapper = new QueryWrapper<>();
        wrapper.eq("NAME", table.getOriginalTableName());
        Table tableInfo = this.getOne(wrapper);
        if (StringUtils.isNull(tableInfo) || StringUtils.isBlank(tableInfo.getId())) {
            throw new BusinessException("获取修改前表信息失败，请稍后重试！");
        }
        tableInfo.setUpdateTime(new Date());
        tableInfo.setUpdateBy(SecurityUtils.getUsername());
        tableInfo.setStatus(YssStatusEnum.DELETED.getCode());
        this.updateById(tableInfo);
    }

    /**
     * 删除表信息
     *
     * @param table
     */
    @Transactional
    public boolean deleteTable(Table table) {
        try {
            TableInfoUtil.handleTableVersion(table.getHisVersion()); // 替换表名
            //删除表字段信息
            QueryWrapper<TableDetail> detailQueryWrapper = new QueryWrapper<>();
            detailQueryWrapper.in("TABLE_ID", table.getIdList());
            // 删除表字段对应的模块，客户和报表信息
            // 查询删除表的所有字段id 集合
            List<TableDetail> listDetail = tableDetailMapper.selectList(detailQueryWrapper);
            if (StringUtils.isNotEmpty(listDetail)) {
                List<String> tempList = listDetail.stream().map(TableDetail::getId).collect(Collectors.toList());
                if (StringUtils.isNotEmpty(tempList)) {
                    TableDetail tableDetail = new TableDetail();
                    tableDetail.setIdList(tempList);
                    tableDetail.setHisVersion(table.getHisVersion());
                    tableDetailService.delReportTableDetail(tableDetail);
                }
            }
            tableDetailMapper.delete(detailQueryWrapper);
            //删除表和客户信息关联关系
            QueryWrapper<DataCustomer> wrapperCustomer = new QueryWrapper<>();
            wrapperCustomer.in("DATA_ID", table.getIdList());
            wrapperCustomer.eq("DATA_CODE", ReportWorldEnum.REPORT_TABLE_CODE.getCode());
            dataCustomerMapper.delete(wrapperCustomer);
            //删除表和模块信息关联关系
            QueryWrapper<DataModular> wrapperModular = new QueryWrapper<>();
            wrapperModular.in("DATA_ID", table.getIdList());
            wrapperModular.eq("DATA_CODE", ReportWorldEnum.REPORT_TABLE_CODE.getCode());
            dataModularMapper.delete(wrapperModular);
            //删除表和报表信息关联关系
            QueryWrapper<DataReport> wrapperReport = new QueryWrapper<>();
            wrapperReport.in("DATA_ID", table.getIdList());
            wrapperReport.eq("DATA_CODE", ReportWorldEnum.REPORT_TABLE_CODE.getCode());
            dataReportMapper.delete(wrapperReport);
            // 表的修改记录，表的关联信息,索引信息
            QueryWrapper<DataDemandBug> updateInfoQueryWrapper = new QueryWrapper<>();
            updateInfoQueryWrapper.eq("DATA_CODE", ReportWorldEnum.REPORT_TABLE_CODE.getCode());
            updateInfoQueryWrapper.in("DATA_ID", table.getIdList());
            dataDemandBugMapper.delete(updateInfoQueryWrapper);
            QueryWrapper<TableIndexed> indexedQueryWrapper = new QueryWrapper<>();
            indexedQueryWrapper.in("TABLE_ID", table.getIdList());
            tableIndexedMapper.delete(indexedQueryWrapper);
            return this.removeByIds(table.getIdList());
        } finally {
            RequestDataHelper.removeThreadLocal();
        }
    }

    /**
     * 批量修改表信息
     *
     * @param table
     * @throws Exception
     */
    @Transactional
    public void batchUpdateTableInfo(Table table) {
        if (StringUtils.isEmpty(table.getIdList())) {
            throw new BusinessException("获取批量修改数据信息失败，请稍后重试！");
        }
        try {
            TableInfoUtil.handleTableVersion(table.getHisVersion()); // 替换表名
            for (String id : table.getIdList()) {
                if (StringUtils.isEmpty(id)) {
                    continue;
                }
                table.setId(id);
                // 批量修改了对应的模块 客户 报表，就先删除在插入
                if (StringUtils.isNotEmpty(table.getStrCustomer()) || table.isClearCustomer()) {
                    //删除表和客户信息关联关系
                    QueryWrapper<DataCustomer> wrapperCustomer = new QueryWrapper<>();
                    wrapperCustomer.in("DATA_ID", table.getId());
                    wrapperCustomer.eq("DATA_CODE", ReportWorldEnum.REPORT_TABLE_CODE.getCode());
                    //  dataCustomerService.remove(wrapperCustomer);
                    dataCustomerMapper.delete(wrapperCustomer);
                }
                if (StringUtils.isNotEmpty(table.getStrModular()) || table.isClearModular()) {
                    //删除表和模块信息关联关系
                    QueryWrapper<DataModular> wrapperModular = new QueryWrapper<>();
                    wrapperModular.in("DATA_ID", table.getId());
                    wrapperModular.eq("DATA_CODE", ReportWorldEnum.REPORT_TABLE_CODE.getCode());
                    //dataModularService.remove(wrapperModular);
                    dataModularMapper.delete(wrapperModular);
                }
                if (StringUtils.isNotEmpty(table.getStrReport()) || table.isClearReport()) {
                    //删除表和报表信息关联关系
                    QueryWrapper<DataReport> wrapperReport = new QueryWrapper<>();
                    wrapperReport.in("DATA_ID", table.getId());
                    wrapperReport.eq("DATA_CODE", ReportWorldEnum.REPORT_TABLE_CODE.getCode());
                    // dataReportService.remove(wrapperReport);
                    dataReportMapper.delete(wrapperReport);
                }
                this.addTableInfo(table);  // 保存表字段对应的客户，模块，报表信息
                Table tableUpdate = new Table();
                UpdateWrapper<Table> wrapper = new UpdateWrapper<>();
                wrapper.eq("ID", id);
                boolean falg = false;
                tableUpdate.setId(id);
                if (null != table.getStatus()) {
                    tableUpdate.setStatus(table.getStatus());
                    falg = true;
                }
                if (null != table.getLayered()) {
                    tableUpdate.setLayered(table.getLayered());
                    falg = true;
                }
                if (StringUtils.isNotBlank(table.getVersion())) {
                    tableUpdate.setVersion(table.getVersion());
                    falg = true;
                }
                if (null != table.getFtype()) {
                    tableUpdate.setFtype(table.getFtype());
                    falg = true;
                }
                if (null != table.getFsource()) {
                    tableUpdate.setFsource(table.getFsource());
                    falg = true;
                }
                if (StringUtils.isNotBlank(table.getRemark())) {
                    tableUpdate.setRemark(table.getRemark());
                    falg = true;
                }
                if (falg) {
                    tableUpdate.setUpdateTime(new Date());
                    tableUpdate.setUpdateBy(SecurityUtils.getUsername());
                    this.update(tableUpdate, wrapper);
                }
            }
            ConnectionHolder holder = (ConnectionHolder) TransactionSynchronizationManager.getResource(this.dataSource);
            Connection connection = holder.getConnection();
            if (null == connection) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                throw new BusinessException("获取数据库连接出错，请稍后重试！");
            }
            String msgInfo = databaseCheckService.checkDataBaseAllByCode(ReportWorldEnum.REPORT_TABLE_CODE.getDesc(), connection, "");
            if (StringUtils.isNotEmpty(msgInfo)) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                throw new BusinessException(msgInfo);
            }
        } finally {
            RequestDataHelper.removeThreadLocal();
        }
    }

    /**
     * 导出建表语句
     */
    public String tableCreateInfo(String queryJson) {
        Map<String, String> mapType = JSON.parseObject(queryJson, LinkedHashMap.class);
        String hisVersion = String.valueOf(mapType.get("hisVersion"));
        TableInfoUtil.handleTableVersion(hisVersion); // 替换表名
        List<Table> list = this.queryReportWorldTable(queryJson);
        if (StringUtils.isEmpty(list)) {
            throw new BusinessException("没有获取到表结构信息，请稍后重试！");
        }
        StringBuffer buffer = new StringBuffer();
        String ftype = YssDataBaseEnum.ORACLE.getCode();
        if (StringUtils.isNotEmpty(mapType.get("DATABASETYPE"))) {
            ftype = mapType.get("DATABASETYPE");
        }
        for (Table table : list) {
            if (StringUtils.isNull(table)) {
                continue;
            }

            List<TableDetail> detailList = table.getListTableDetail();
            if (StringUtils.isEmpty(detailList)) {
                continue;
            }
            buffer.append(TableInfoUtil.creatTable(table, detailList, ftype));
        }
        return buffer.toString();
    }

    /**
     * 查询表信息，提供给页面导出数据使用，传入id有值就按照选中的导出，没有选择就导出全量的
     */
    public List<Table> queryReportWorldTable(String queryJson) {
        try {
            // 表结构信息
            Table tableInfo = JSONObject.parseObject(queryJson, Table.class);
            List<Table> tableList = this.selectTableList(tableInfo, false);
            QueryWrapper<TableDetail> tableDetailQueryWrapper = new QueryWrapper<>();
            if (StringUtils.isEmpty(tableList)) {
                log.error("没有获取到表信息！");
                return null;
            }
            List<String> tableIds = tableList.stream().map(e -> e.getId()).collect(Collectors.toList());
            if (StringUtils.isEmpty(tableIds)) {
                log.error("没有获取到表字段信息！");
                return null;
            }
            tableDetailQueryWrapper.in("TABLE_ID", tableIds);
            if (StringUtils.isEmpty(tableList)) {
                log.error("没有获取到表字段信息！");
                return null;
            }
            // 表字段信息
            tableDetailQueryWrapper.orderByAsc("ORDER_NUM");
            tableDetailQueryWrapper.eq("STATUS", YssStatusEnum.NORMAL.getCode());
            TableInfoUtil.handleTableVersion(tableInfo.getHisVersion()); // 替换表名
            List<TableDetail> tableDetailList = tableDetailMapper.selectList(tableDetailQueryWrapper);
            if (StringUtils.isEmpty(tableDetailList)) {
                log.error("没有获取到表字段信息！");
                return null;
            }
            // 索引信息
            Map<String, List<TableIndexed>> mapTableIndexed = tableIndexedService.getTableIndexedMap(true);
            // 表字段处理
            Map<String, List<TableDetail>> mapTableDetail = new HashMap<>();
            for (TableDetail detail : tableDetailList) {
                if (StringUtils.isNull(detail) || StringUtils.isBlank(detail.getTableId())) {
                    continue;
                }
                if (mapTableDetail.containsKey(detail.getTableId())) {
                    List<TableDetail> list = mapTableDetail.get(detail.getTableId());
                    list.add(detail);
                    mapTableDetail.put(detail.getTableId(), list);
                } else {
                    List<TableDetail> list = new ArrayList<>();
                    list.add(detail);
                    mapTableDetail.put(detail.getTableId(), list);
                }
            }
            if (StringUtils.isEmpty(mapTableDetail)) {
                log.error("没有获取到表字段信息！");
            }
            for (Table table : tableList) {
                if (StringUtils.isNull(table) || StringUtils.isBlank(table.getId())) {
                    continue;
                }
                // 表字段信息 没有字段信息的表跳过
                if (!mapTableDetail.containsKey(table.getId()) || StringUtils.isEmpty(mapTableDetail.get(table.getId()))) {
                    log.error(table.getChineseName() + "没有获取到字段信息！");
                    continue;
                }
                table.setListTableDetail(mapTableDetail.get(table.getId()));
                if (!StringUtils.isEmpty(mapTableIndexed)) {
                    table.setListIndexed(mapTableIndexed.get(table.getId()));
                }
            }
            return tableList;
        } finally {
            RequestDataHelper.removeThreadLocal();
        }
    }


    /**
     * 获取一张表信息到库里
     *
     * @throws Exception
     */
    @Transactional
    public void readTableInfo(Table table) {
        if (StringUtils.isBlank(table.getName())) {
            throw new BusinessException("请在表名处输入要获取的表名信息！");
        }
        Connection conn = null;
        try {
            TableInfoUtil.handleTableVersion(table.getHisVersion()); // 替换表名
            DynamicRoutingDataSource ds = (DynamicRoutingDataSource) dataSource;
            Connection slave = ds.getDataSource("slave").getConnection();
            conn = slave.unwrap(OracleConnection.class);
            List<TableInfo> list = JdbcUtil.getTablesList(conn, table.getName().toUpperCase());
            ConnectionHolder holder = (ConnectionHolder) TransactionSynchronizationManager.getResource(this.dataSource);
            Connection connection = holder.getConnection();
            if (null == connection) {
                throw new BusinessException("获取数据库连接出错，请稍后重试！");
            }
            for (TableInfo tableInfo : list) {
                if (null == tableInfo || StringUtils.isBlank(tableInfo.getName())) {
                    continue;
                }
                QueryWrapper<Table> wrapper = new QueryWrapper<>();
                wrapper.eq("NAME", tableInfo.getName());
                Table tableOld = this.getOne(wrapper);
                if (null != tableOld) { //表已经存在
                    this.updateTableInfo(tableOld, conn, connection);
                } else {
                    this.insertTableInfo(tableInfo.getName(), conn, connection);
                }
            }
        } catch (Exception ex) {
            log.error(ex.getMessage());
            throw new BusinessException(ex.getMessage());
        } finally {
            RequestDataHelper.removeThreadLocal();
            try {
                JdbcUtil.close(conn);
            } catch (Exception ex) {
                log.error(ex.getMessage());
            }
        }
    }

    /**
     * 表结构已经存在更新表结构信息
     *
     * @param table
     * @throws Exception
     */
    public void updateTableInfo(Table table, Connection conn, Connection connection) throws Exception {
        try {
            // 获取这张表的信息
            Map<TableInfo, List<ColumnInfo>> map = JdbcUtil.getTableInfoMap(table.getName(), conn);
            if (CollectionUtils.isEmpty(map)) {
                throw new BusinessException("数据库没有获取到对应报表的语句用到的表信息，请稍后重试！");
            }
            for (Map.Entry<TableInfo, List<ColumnInfo>> entry : map.entrySet()) {
                TableInfo tableInfo = entry.getKey();
                if (null == tableInfo) {
                    continue;
                }
                Table addTable = new Table();
                String tableId = table.getId();
                addTable.setId(tableId);
                addTable.setName(tableInfo.getName());
                addTable.setChineseName(tableInfo.getRemarks());
                if (StringUtils.isBlank(tableInfo.getRemarks())) {
                    addTable.setName(tableInfo.getName());
                }
                addTable.setStatus(YssStatusEnum.NORMAL.getCode());
                //addTable.setLayered(6);
                addTable.setUpdateTime(new Date());
                addTable.setUpdateBy(SecurityUtils.getUsername());
                this.updateById(addTable);
                // 索引处理
                this.insertTableIndexed(tableInfo, tableId, connection);
                if (CollectionUtils.isEmpty(entry.getValue())) {
                    log.error(tableInfo.getName() + "没有获取到对应的字段信息!");
                    continue;
                }
                int i = 1;
                // 删除所有字段信息
              /*  QueryWrapper<TableDetail> wrapperCloum = new QueryWrapper<>();
                wrapperCloum.eq("TABLE_ID", tableId);
                tableDetailService.remove(wrapperCloum);*/
                // 获取库里的所有字段
                for (ColumnInfo columnInfo : entry.getValue()) {
                    if (null == columnInfo) {
                        continue;
                    }
                    QueryWrapper<TableDetail> wrapper2 = new QueryWrapper<>();
                    wrapper2.eq("COLUMN_NAME", columnInfo.getName());
                    wrapper2.eq("TABLE_ID", tableId);
                    TableDetail reportWorldTableDetail = tableDetailMapper.selectOne(wrapper2);
                    if (null != reportWorldTableDetail) { // 已经存在该字段了
                        TableDetail tableDetail = TableInfoUtil.getReportTableDetail(columnInfo, tableId);
                        tableDetail.setId(reportWorldTableDetail.getId());
                        tableDetail.setOrderNum(i);
                        tableDetail.setStatus(YssStatusEnum.NORMAL.getCode());
                        tableDetail.setUpdateTime(new Date());
                        tableDetail.setUpdateBy(SecurityUtils.getUsername());
                        // tableDetailService.updateById(tableDetail);
                        tableDetailMapper.updateById(tableDetail);
                    } else {
                        TableDetail tableDetail = TableInfoUtil.getReportTableDetail(columnInfo, tableId);
                        tableDetail.setOrderNum(i);
                        tableDetail.setStatus(YssStatusEnum.NORMAL.getCode());
                        tableDetail.setUpdateTime(new Date());
                        tableDetail.setUpdateBy(SecurityUtils.getUsername());
                        //tableDetailService.save(tableDetail);
                        tableDetailMapper.insert(tableDetail);
                    }
                    i++;
                }
            }
        } catch (Exception ex) {
            log.error(ex.getMessage());
            throw new BusinessException(ex.getMessage());
        }
    }

    /**
     * 表不存在，新增表信息
     *
     * @param tableName
     * @throws Exception
     */
    public void insertTableInfo(String tableName, Connection conn, Connection connection) throws Exception {
        try {
            // 获取这张表的信息
            Map<TableInfo, List<ColumnInfo>> map = JdbcUtil.getTableInfoMap(tableName, conn);
            if (CollectionUtils.isEmpty(map)) {
                throw new BusinessException("数据库没有获取到对应报表的语句用到的表信息，请稍后重试！");
            }
            for (Map.Entry<TableInfo, List<ColumnInfo>> entry : map.entrySet()) {
                TableInfo tableInfo = entry.getKey();
                if (null == tableInfo) {
                    continue;
                }
                Table addTable = new Table();
                String tableId = IdUtils.fastSimpleUUID();
                addTable.setId(tableId);
                addTable.setName(tableInfo.getName());
                addTable.setChineseName(tableInfo.getRemarks());
                if (StringUtils.isBlank(tableInfo.getRemarks())) {
                    addTable.setName(tableInfo.getName());
                }
                addTable.setStatus(YssStatusEnum.NORMAL.getCode());
                addTable.setCreateTime(new Date());
                addTable.setCreateBy(SecurityUtils.getUsername());
                //addTable.setLayered(6);
                this.save(addTable);
                // 索引处理
                String msg = this.insertTableIndexed(tableInfo, tableId, connection);
                if (StringUtils.isNotEmpty(msg)) {
                    throw new BusinessException(msg);
                }
                if (CollectionUtils.isEmpty(entry.getValue())) {
                    log.error(tableInfo.getName() + "没有获取到对应的字段信息!");
                    continue;
                }
                int i = 1;
                for (ColumnInfo columnInfo : entry.getValue()) {
                    if (null == columnInfo) {
                        continue;
                    }
                    TableDetail tableDetail = TableInfoUtil.getReportTableDetail(columnInfo, tableId);
                    tableDetail.setOrderNum(i);
                    tableDetail.setStatus(YssStatusEnum.NORMAL.getCode());
                    tableDetail.setCreateTime(new Date());
                    tableDetail.setCreateBy(SecurityUtils.getUsername());
                    tableDetailMapper.insert(tableDetail);
                    i++;
                }
            }
        } catch (Exception ex) {
            log.error(ex.getMessage());
            throw new BusinessException("新增表信息失败，请稍后重试！" + ex.getMessage());
        }
    }

    /**
     * 插入表索引信息
     *
     * @throws Exception
     */
    public String insertTableIndexed(TableInfo tableInfo, String tableId, Connection connection) throws Exception {
        if (null == tableInfo || StringUtils.isBlank(tableId)) {
            return null;
        }
        QueryWrapper<TableIndexed> wrapper = new QueryWrapper<>();
        //删除表的索引信息
        wrapper.eq("TABLE_ID", tableId);
        tableIndexedMapper.delete(wrapper);
        //重新插入
        List<IndexInfo> list = tableInfo.getListIndexInfo();
        if (CollectionUtils.isEmpty(list)) {
            return null;
        }
        //  List<TableIndexed> tableIndexeds = new ArrayList<>();
        for (IndexInfo info : list) {
            if (null == info) {
                continue;
            }
            TableIndexed worldTableIndexed = new TableIndexed();
            worldTableIndexed.setId(IdUtils.fastSimpleUUID());
            worldTableIndexed.setTableId(tableId);
            worldTableIndexed.setIndexedName(info.getIndexName());
            worldTableIndexed.setIndexedColumnName(info.getColumnName());
            // 索引列排序
            String indexAscOrDesc = ("A".equals(info.getAscOrDesc())) ? "ASC" : ("B".equals(info.getAscOrDesc())) ? "DESC" : "";
            worldTableIndexed.setIndexedAscDesc(indexAscOrDesc);
            if (StringUtils.isBlank(info.getIndexType())) {
                worldTableIndexed.setIndexedType(1);
            } else {
                worldTableIndexed.setIndexedType(Integer.valueOf(info.getIndexType()));
            }
            worldTableIndexed.setIndexedColumnSequence(Integer.valueOf(info.getOrdinalPosition()));
            // tableIndexeds.add(worldTableIndexed);
            tableIndexedMapper.insert(worldTableIndexed);
        }
        //tableIndexedService.saveBatch(tableIndexeds);
        String msgInfo = databaseCheckService.checkDataBaseAllByCode(ReportWorldEnum.REPORT_TABLE_INDEXED_CODE.getCode(), connection, "");
        if (StringUtils.isNotEmpty(msgInfo)) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return msgInfo;
        }
        return null;
    }


    /**
     * 导出表结构信息Execl
     *
     * @throws Exception
     */
    public void exportExeclTableInfo(HttpServletResponse response, List<Table> list) {
        String tableName = "";
        try {
            Map<String, String> stringMap = new HashMap<>();
            List<Table> worldTableList = new ArrayList<>();
            List<TableDetail> worldTableDetailList = new ArrayList<>();
            // 报表世界所在分层
            Map<String, String> mapTableLayered = DictUtils.getDictCacheMap(ReportWorldEnum.REPORT_TABLE_LAYERED.getCode());
            for (Table table : list) {
                if (StringUtils.isNull(table)) {
                    continue;
                }
                tableName = table.getName();
                if (StringUtils.isNotEmpty(mapTableLayered)) {
                    table.setStrLayered(mapTableLayered.get(String.valueOf(table.getLayered())));
                }
                if (stringMap.containsKey(table.getName())) {
                    continue;
                }
                QueryWrapper<TableDetail> detailQueryWrapper = new QueryWrapper<>();
                detailQueryWrapper.in("TABLE_ID", table.getId());
                detailQueryWrapper.eq("STATUS", YssStatusEnum.NORMAL.getCode());
                // 删除表字段对应的模块，客户和报表信息
                // 查询删除表的所有字段id 集合
                List<TableDetail> detailList = tableDetailMapper.selectList(detailQueryWrapper);
                if (CollectionUtils.isEmpty(detailList)) {
                    continue;
                }
                worldTableList.add(table);
                for (TableDetail tableDetail : detailList) {
                    if (StringUtils.isNull(tableDetail)) {
                        continue;
                    }
                    String columnType = TableInfoUtil.handleCloum(tableDetail, true);
                    if (StringUtils.isBlank(columnType)) {
                        continue;
                    }
                    tableDetail.setStrColumnType(columnType);
                    tableDetail.setTableName(table.getName());
                    tableDetail.setTableChineseName(table.getChineseName());
                    tableDetail.setStrColumnNull(null != tableDetail.getColumnNull() && 1 == tableDetail.getColumnNull() ? "是" : "否");
                    worldTableDetailList.add(tableDetail);
                }
                stringMap.put(table.getName(), table.getName());
            }
            ExcelExp e1 = new ExcelExp("表信息", list, Table.class);
            ExcelExp e2 = new ExcelExp("表明细信息", worldTableDetailList, TableDetail.class);
            List<ExcelExp> mysheet = new ArrayList<>();
            mysheet.add(e1);
            mysheet.add(e2);
            EasyExeclUtil.exportExcelManySheet(response, mysheet);
        } catch (Exception ex) {
            throw new BusinessException(tableName + "导出文件失败，请稍后重试！" + ex.getMessage());
        }
    }


    /**
     * 读取设计文档  同步字典和业务主键
     */
    public String readDemandDesign(MultipartFile multipartfile, boolean updateSupport, String hisVersion) {
        StringBuffer buffer = new StringBuffer();
        try {
            TableInfoUtil.handleTableVersion(hisVersion); // 替换表名
            String fileName = multipartfile.getOriginalFilename();
            fileName = fileName.substring(0, fileName.lastIndexOf("."));
            String name = updateSupport ? "基础页面" : "设计文档";
            if (!StringUtils.oneOf(fileName, name)) {
                throw new BusinessException("请选择正确的" + name + "！");

            }
            String sheetName = updateSupport ? "页面目录" : "报表目录";
            List<List<Object>> listSize = FileUtils.readerExcelObj(FileUtils.MultipartFileToFile(multipartfile), sheetName);
            if (CollectionUtils.isEmpty(listSize) || listSize.size() <= 2) {
                throw new BusinessException("没有获取导报表目录的sheet页信息！");
            }
            String xlsxTableCloumName = updateSupport ? "字段英文名" : "字段名";
            int num = updateSupport ? 3 : 5;
            for (int k = 2; k < listSize.size(); k++) {
                if (null == listSize.get(k) || null == listSize.get(k).get(num) || StringUtils.isEmpty(listSize.get(k).get(num).toString())) {
                    continue;
                }
                String listSheetName = listSize.get(k).get(num).toString();
                List<List<Object>> list = null;
                try {
                    list = FileUtils.readerExcelObj(FileUtils.MultipartFileToFile(multipartfile), listSheetName);
                } catch (Exception ex) {
                    log.error(listSheetName + ex.getMessage());
                }
                if (CollectionUtils.isEmpty(list)) {
                    log.error("文件中没有获取到数据！");
                    continue;
                }
                String tableName = "";
                Map<Integer, TableDetail> map = new HashMap();
                for (int m = 0; m < list.size(); m++) {
                    List<Object> objects = list.get(m);
                    if (null == objects.get(0) || StringUtils.isBlank(objects.get(0).toString())) {
                        continue;
                    }
                    if (StringUtils.oneOf(objects.get(0).toString(), "落地表")) {
                        tableName = objects.get(1).toString();
                        if (tableName.indexOf("→") > -1) {
                            tableName = tableName.split("→")[0].trim();
                        } else if (tableName.indexOf("（") > -1) {
                            tableName = tableName.split("（")[0].trim();
                        }
                    }
                    if (StringUtils.oneOf(objects.get(0).toString(), xlsxTableCloumName)) {
                        QueryWrapper<Table> wrapper = new QueryWrapper<>();
                        wrapper.eq("NAME", tableName);
                        Table table = this.getOne(wrapper);
                        if (null == table) {
                            buffer.append(tableName).append("系统中没有获取到表结构信息！").append("\r\n");
                            break;
                        }
                        for (int i = 1; i < objects.size(); i++) {
                            if (null == objects.get(i) || StringUtils.isBlank(objects.get(i).toString())) {
                                continue;
                            }
                            String columName = objects.get(i).toString().trim();
                            QueryWrapper<TableDetail> wrapper2 = new QueryWrapper<>();
                            wrapper2.eq("COLUMN_NAME", columName);
                            wrapper2.eq("TABLE_ID", table.getId());
                            TableDetail tableDetail = tableDetailMapper.selectOne(wrapper2);
                            if (null == tableDetail) {
                                buffer.append(tableName).append("字段" + columName).append("系统中没有获取到字段信息！").append("\r\n");
                            }
                            map.put(i, tableDetail);
                        }
                        continue;
                    }
                    if (StringUtils.oneOf(objects.get(0).toString(), "业务主键") && !CollectionUtils.isEmpty(map)) {
                        for (int i = 1; i < objects.size(); i++) {
                            if (null == objects.get(i) || StringUtils.isBlank(objects.get(i).toString())) {
                                continue;
                            }
                            String columName = objects.get(i).toString();
                            TableDetail tableDetail = map.get(i);
                            if (null == tableDetail) {
                                continue;
                            }
                            if ("Y".equals(objects.get(i).toString())) {
                                tableDetail.setBusinessPrimaryKey(1);
                            } else {
                                tableDetail.setBusinessPrimaryKey(2);
                            }
                        }
                        continue;
                    }
                    if (StringUtils.oneOf(objects.get(0).toString(), "字典") && !CollectionUtils.isEmpty(map)) {
                        for (int i = 1; i < objects.size(); i++) {
                            if (null == objects.get(i) || StringUtils.isBlank(objects.get(i).toString())) {
                                continue;
                            }
                            TableDetail tableDetail = map.get(i);
                            if (null == tableDetail) {
                                continue;
                            }
                            String codeName = objects.get(i).toString();
                            if (codeName.indexOf("-") > -1) {
                                tableDetail.setCodeName(codeName.split("-")[0].trim());
                            } else {
                                tableDetail.setCodeName(codeName);
                            }
                        }
                        break;
                    }
                }
                if (CollectionUtils.isEmpty(map)) {
                    continue;
                }
                for (Map.Entry<Integer, TableDetail> entry : map.entrySet()) {
                    TableDetail tableDetail = entry.getValue();
                    if (null == tableDetail) {
                        continue;
                    }
                    tableDetailMapper.updateById(tableDetail);
                }
                buffer.append(tableName).append(map.size() + "条数据！").append("\r\n");
            }
        } catch (Exception ex) {
            log.error(ex.getMessage());
            throw new BusinessException("更新表业务主键和字典信息失败！" + ex.getMessage());
        } finally {
            RequestDataHelper.removeThreadLocal();
        }
        return buffer.toString();
    }

}
